package org.webdb.jdbc;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import org.webdb.core.IOUtils;
import org.webdb.core.config.ConfigProcessor;
import org.webdb.core.config.DatabaseConfig;
import org.webdb.core.database.DataBase;

import com.jolbox.bonecp.BoneCPDataSource;

public class JDBCConfigProcessor implements ConfigProcessor {

    public DataBase proccess(DatabaseConfig config, ResourceResolver resolver)
            throws Exception {

        DataSource ds = createDataSource(config, resolver);

        return new JDBCDataBase(config.getName(), ds, config);
    }

    private DataSource createDataSource(DatabaseConfig config,
            ResourceResolver resolver) throws ClassNotFoundException {
        // TODO Auto-generated method stub
        String driver = config.getAs("driver");
        Class<?> cl = this.getClass().getClassLoader().loadClass(driver);
        try {
            cl.newInstance();
        } catch (InstantiationException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        BoneCPDataSource ds = new BoneCPDataSource();
        ds.setJdbcUrl(config.<String> getAs("url"));
        ds.setUsername(config.<String> getAs("username"));
        ds.setPassword(config.<String> getAs("password"));
        DatabaseConfig poolCfg = config.<DatabaseConfig> getAs("pool");
        ds.setPartitionCount(poolCfg.<Integer> getAs("partition"));
        ds.setPartitionCount(poolCfg.<Integer> getAs("max"));
        ds.setMinConnectionsPerPartition(poolCfg.<Integer> getAs("min"));
        ds.setAcquireIncrement(poolCfg.<Integer> getAs("increment"));
        String startScript = null;
        try {
            startScript = config.getAs("startScript");
        } catch (Exception e) {

        }

        if (startScript != null) {
            if (startScript.startsWith("@")) {
                try {
                    InputStream in = resolver.getStream(startScript
                            .substring(1));
                    startScript = IOUtils.toString(in);
                } catch (Exception e) {
                    throw new JDBCException(toString(config.getName())
                            + " Loading StartScript "
                            + startScript.substring(1), e);
                }
            }
            try {
                executeScript(ds, startScript);
            } catch (Exception e) {
                throw new JDBCException(toString(config.getName())
                        + " Running StartScript", e);
            }
        }
        return ds;
    }

    private void executeScript(BoneCPDataSource ds, String sqlScript)
            throws SQLException {
        Connection connection = ds.getConnection();
        Statement stmt = connection.createStatement();
        stmt.execute(sqlScript);
        connection.close();
    }

    private String toString(String name) {
        return JDBCConfigProcessor.class.getSimpleName() + "[" + name + "]";
    }
}
